<?php
namespace App\MessageHandler;

use App\AppClassFactory;
use App\ImageOptimizer;
use App\Message\CommentMessage;
use App\Notification\CommentReviewNotification;
use App\Repository\CommentRepository;
use App\SpamChecker;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bridge\Twig\Mime\NotificationEmail;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Notifier\NotifierInterface;
use Symfony\Component\Workflow\WorkflowInterface;

/**
 * 运行（symfony console messenger:consume async -vv）
 * 守护进程运行（symfony run -d --watch=config,src,templates,vendor symfony console messenger:consume async）
 * Class CommentMessageHandler
 * @package App\MessageHandler
 */
class CommentMessageHandler
{
    private $spamChecker;
    private $entityManager;
    private $commentRepository;
    private $workflow;
    private $bus;
    private $logger;
    private $mailer;
    private $imageOptimizer;
    private $notifier;

    public function __construct(EntityManagerInterface $entityManager, SpamChecker $spamChecker,ImageOptimizer $imageOptimizer, WorkflowInterface $commentStateMachine, MessageBusInterface $bus, CommentRepository $commentRepository,MailerInterface $mailer,NotifierInterface $notifier,LoggerInterface $logger = null)
    {
        $this->entityManager = $entityManager;
        $this->spamChecker = $spamChecker;
        $this->commentRepository = $commentRepository;
        $this->workflow = $commentStateMachine;
        $this->bus = $bus;
        $this->logger = $logger;
        $this->mailer = $mailer;
        $this->notifier = $notifier;
        $this->imageOptimizer = $imageOptimizer;
    }

    public function __invoke(CommentMessage $message)
    {
        $comment = $this->commentRepository->find($message->getId());
        if (!$comment) {
            return;
        }

//        if (2 === $this->spamChecker->getSpamScore($comment, $message->getContext())) {
//            $comment->setState('spam');
//        } else {
//            $comment->setState('published');
//        }

        if ($this->workflow->can($comment, 'accept')) {
            $score = $this->spamChecker->getSpamScore($comment, $message->getContext());
            $transition = 'accept';
            if (2 === $score) {
                $transition = 'reject_spam';
            } elseif (1 === $score) {
                $transition = 'might_be_spam';
            }
            $this->workflow->apply($comment, $transition);
            $this->entityManager->flush();
            $this->bus->dispatch($message);
        } elseif ($this->workflow->can($comment, 'publish') || $this->workflow->can($comment, 'publish_ham')) {
            $this->workflow->apply($comment, $this->workflow->can($comment, 'publish') ? 'publish' : 'publish_ham');
            $this->entityManager->flush();
//            $this->mailer->send((new NotificationEmail())
//                ->subject('New comment posted')
//                ->htmlTemplate('emails/comment_notification.html.twig')
//                ->from("fasf@qq.com")
//                ->to("fasf@qq.com")
//                ->context(['comment' => $comment])
//            );
            $notification = new CommentReviewNotification($comment, $message->getReviewUrl());
            $this->notifier->send($notification, ...$this->notifier->getAdminRecipients());
        } elseif ($this->workflow->can($comment, 'optimize')) {
            if ($comment->getPhotoFilename()) {
                $upload_photos_dir = AppClassFactory::getContainer()->getParameter("upload_photos");
                $this->imageOptimizer->resize($upload_photos_dir.'/'.$comment->getPhotoFilename());
            }
            $this->workflow->apply($comment, 'optimize');
            $this->entityManager->flush();
        } elseif ($this->logger) {
            $this->logger->debug('Dropping comment message', ['comment' => $comment->getId(), 'state' => $comment->getState()]);
        }
        $this->entityManager->flush();
    }
}